﻿using AutoMapper;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using Ross.EntityFramework;
using Ross.EntityFramework.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Ross.Service
{
    public class MonthlyPlanService : BaseService, IDisposable
    {
        private TranDbContext dbContext;
        public IRepository<Targets, int> repository;
        public IRepository<Users, int> repository2;

        public MonthlyPlanService(string nameOrConnectionString)
        {
            dbContext = new TranDbContext(nameOrConnectionString);
            repository = new Repository<Targets, int>(dbContext);
            repository2 = new Repository<Users, int>(dbContext);
        }

        /// <summary>
        /// 返回登录时选择的年份对应员工可查阅的所有部门的所有计划信息
        /// </summary>
        /// <returns></returns>
        public ResultDto<List<Dto.MonthlyPlan>> Get()
        {
            ResultDto<List<Dto.MonthlyPlan>> result = new ResultDto<List<Dto.MonthlyPlan>>();
            
            try
            {
                //var currtUser = Thread.CurrentPrincipal;
                if (!string.IsNullOrEmpty(username))
                {
                    //string username = currtUser.Identity.Name.Split(':')[0];
                    //string year = DateTime.Parse(currtUser.Identity.Name.Split(':')[1]).ToString("yyyy");
                    var obj1 = repository2.GetAllList(o => o.UserName == username || o.EmpID == username).FirstOrDefault();
                    string[] departments = obj1.AuthorizedDepartment.Split(',');
                    var obj = repository.GetAllList(o => o.StartingTime.Year == year && departments.Contains(o.Department) && o.Depth >= 3 && o.ApprovalStatus == "已审核").ToList();
                    
                    if (obj != null)
                    {
                        result.status = 200;
                        result.datas = Mapper.Map<List<Dto.MonthlyPlan>>(obj);
                    }
                    else
                    {
                        result.message = "user is not exist";
                        result.status = 500;
                    }
                }
                else
                {
                    result.message = "Unable to access unauthorized app";
                    result.status = 500;
                }
            }
            catch (Exception e)
            {
                result.message = e.Message;
                result.status = 500;
            }
            return result;

        }

        /// <summary>
        /// 根据条件返回对应数据
        /// </summary>
        /// <param name="month">月份</param>
        /// <param name="week">周</param>
        /// <param name="department">部门</param>
        /// <param name="Responsible">责任人</param>
        /// <returns></returns>
        public ResultDto<List<Dto.MonthlyPlan>> Get(string name="",string month = "",string week = "",string department = "",string Responsible = "")
        {
            ResultDto<List<Dto.MonthlyPlan>> result = new ResultDto<List<Dto.MonthlyPlan>>();
            Expression<Func<Targets, bool>> expression = o => o.ID > 0;
            try
            {
                //var currtUser = Thread.CurrentPrincipal;
                if (string.IsNullOrEmpty(name))
                {
                    name = username;
                }
                var obj1 = repository2.GetAllList(o => o.UserName == name || o.EmpID == username).FirstOrDefault();
                string[] departments = obj1.AuthorizedDepartment.Split(',');
                expression = expression.ExpressionAnd(o => o.StartingTime.Year == year);
                if (!string.IsNullOrEmpty(month))
                {
                    int m = int.Parse(month);
                    expression = expression.ExpressionAnd(o => o.StartingTime.Year == year && o.StartingTime.Month <= m && o.PlannedCompletionTime.Month >= m);
                }
                if (!string.IsNullOrEmpty(week))
                {
                    Tuple<DateTime, DateTime> tuple = GetFirstEndDayOfWeek(year, int.Parse(week));
                    DateTime start = DateTime.Parse(tuple.Item1.ToString("yyyy-MM-dd"));
                    DateTime end = DateTime.Parse(tuple.Item2.ToString("yyyy-MM-dd"));
                    expression = expression.ExpressionAnd(o => o.StartingTime >= start && o.StartingTime <= end || (o.StartingTime <= start && o.PlannedCompletionTime>=end));
                }
                if (!string.IsNullOrEmpty(department))
                    expression = expression.ExpressionAnd(o => o.Department == department);
                else
                    expression = expression.ExpressionAnd(o => departments.Contains(o.Department));
                if (!string.IsNullOrEmpty(Responsible))
                    expression = expression.ExpressionAnd(o => o.Responsible == Responsible);
                expression = expression.ExpressionAnd(o => o.ApprovalStatus == "已审核" && o.Depth >= 3);
                var obj = repository.GetAllList(expression).ToList();
                if (obj != null)
                {
                    result.status = 200;
                    result.datas = Mapper.Map<List<Dto.MonthlyPlan>>(obj);
                    foreach (var item in result.datas)
                    {
                        if (Panduan(item.ActualCompletionTime))
                            item.ActualCompletionTime = null;
                    }
                }
            }
            catch (Exception e)
            {
                result.message = e.Message;
                result.status = 500;
            }
            return result;
        }

        public void Dispose()
        {
            dbContext.Dispose();
        }

        /// <summary>
        /// 返回文件流供前端下载excel
        /// </summary>
        /// <returns></returns>
        public FileResult ExportExcel_Mo(string name = "", string month = "", string week = "", string department = "", string Responsible = "")
        {
            //ResultDto<FileResult> result = new ResultDto<FileResult>();
            try
            {
                HSSFWorkbook book = new HSSFWorkbook();
                ISheet sheet1 = book.CreateSheet("Sheet1");
                //设置列宽
                for (int i = 0; i < 8; i++)
                {
                    if(i==0)
                        sheet1.SetColumnWidth(i, 7000);
                    sheet1.SetColumnWidth(i,4500);
                }
                    
                //标题设置
                IRow row0 = sheet1.CreateRow(0);
                row0.HeightInPoints = 30;
                IFont fontTitle = book.CreateFont();
                fontTitle.FontHeightInPoints = 12;
                fontTitle.Boldweight = (short)FontBoldWeight.Bold;
                ICellStyle styleTiltle = book.CreateCellStyle();
                styleTiltle.Alignment = HorizontalAlignment.Center;
                styleTiltle.SetFont(fontTitle);
                styleTiltle.VerticalAlignment = VerticalAlignment.Center;
                IFont fontContent = book.CreateFont();
                fontContent.FontHeightInPoints = 12;
                ICellStyle styleContent = book.CreateCellStyle();
                styleContent.Alignment = HorizontalAlignment.CenterSelection;
                styleContent.SetFont(fontContent);
                styleContent.VerticalAlignment = VerticalAlignment.Center;
                string currxzq = "BSC月度计划";
                row0.CreateCell(0).SetCellValue(currxzq);
                sheet1.AddMergedRegion(new CellRangeAddress(0, 0, 0, 7));
                row0.GetCell(0).CellStyle = styleTiltle;
                IRow rowhead = sheet1.CreateRow(1);
                string[] colums = ("计划工作内容|完成标准|计划开始时间|计划完成时间|责任人|进展情况|实际完成日期|备注").Split('|');
                for (int i = 0; i < colums.Length; i++)
                {
                    rowhead.CreateCell(i).SetCellValue(colums[i]);
                    sheet1.AddMergedRegion(new CellRangeAddress(1, 1, i, i));
                    rowhead.GetCell(i).CellStyle = styleContent;
                }
                int RowNum = 2;
                IFont fontContent2 = book.CreateFont();
                fontContent2.FontHeightInPoints = 10;
                ICellStyle styleContent2 = book.CreateCellStyle();
                styleContent2.SetFont(fontContent);
                //ResultDto<List<BSCReports_DpOut>> datas = new ResultDto<List<BSCReports_DpOut>>();
                var datas = Get(name,month,week,department,Responsible).datas;

                if (datas.Count > 0)
                {
                    foreach (var item in datas)
                    {

                        IRow row = sheet1.CreateRow(RowNum);
                        row.CreateCell(0).SetCellValue(item.TargetName);
                        row.GetCell(0).CellStyle = styleContent2;
                        row.CreateCell(1).SetCellValue(item.CompletionCriteria);
                        row.GetCell(1).CellStyle = styleContent2;
                        if (item.StartingTime == Convert.ToDateTime("0001-01-01") || item.StartingTime == null)
                            row.CreateCell(2).SetCellValue("");
                        else
                            row.CreateCell(2).SetCellValue(item.StartingTime.ToString("yyyy-MM-dd"));
                        row.GetCell(2).CellStyle = styleContent2;
                        if (item.PlannedCompletionTime == Convert.ToDateTime("0001-01-01") || item.PlannedCompletionTime == null)
                            row.CreateCell(3).SetCellValue("");
                        else
                            row.CreateCell(3).SetCellValue(item.PlannedCompletionTime.ToString("yyyy-MM-dd"));
                        row.GetCell(3).CellStyle = styleContent2;
                        row.CreateCell(4).SetCellValue(item.Responsible);
                        row.GetCell(4).CellStyle = styleContent2;
                        row.CreateCell(5).SetCellValue(item.Progress);
                        row.GetCell(5).CellStyle = styleContent2;
                        if (item.ActualCompletionTime == Convert.ToDateTime("0001-01-01") || item.ActualCompletionTime == null)
                            row.CreateCell(6).SetCellValue("");
                        else
                            row.CreateCell(6).SetCellValue(item.ActualCompletionTime?.ToString("yyyy-MM-dd"));
                        row.GetCell(6).CellStyle = styleContent2;
                        row.CreateCell(7).SetCellValue(item.TargetDescription);
                        row.GetCell(7).CellStyle = styleContent2;
                        RowNum++;
                    }
                    MemoryStream ms = new MemoryStream();
                    book.Write(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    FileStreamResult file = new FileStreamResult(ms, "application/vnd.ms-excel");
                    file.FileDownloadName = "BSC月度计划报表" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xls";
                    return file;
                }
            }
            catch (Exception e)
            {
                //result.status = 500;
                //result.message = e.Message;
            }
            return null;
        }


        /// <summary>
        /// 根据一年中的第几周获取该周的开始日期与结束日期
        /// </summary>
        /// <param name="year"></param>
        /// <param name="weekNumber"></param>
        /// <param name="culture"></param>
        /// <returns></returns>

        public static Tuple<DateTime, DateTime> GetFirstEndDayOfWeek(int year, int weekNumber)
        {
            CultureInfo culture = CultureInfo.GetCultureInfo("zh-cn");
            System.Globalization.Calendar calendar = culture.Calendar;
            DateTime firstOfYear = new DateTime(year, 1, 1, calendar);
            DateTime targetDay = calendar.AddWeeks(firstOfYear, weekNumber - 1);
            DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;
            while (targetDay.DayOfWeek != firstDayOfWeek)
            {
                targetDay = targetDay.AddDays(-1);
            }
            return Tuple.Create<DateTime, DateTime>(targetDay, targetDay.AddDays(6));
        }

        bool Panduan(DateTime? dateTime)
        {
            if (dateTime == Convert.ToDateTime("0001-01-01") || dateTime == null)
            {
                return true;
            }
            else
                return false;
        }

    }
}
